home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 039a / rzsz1004.zip / ZMR.C < prev    next >
C/C++ Source or Header  |  1989-07-29  |  4KB  |  186 lines

  1. /*
  2.  * File: zmr.c 07-30-1989
  3.  * Copyright 1988, 1989 Omen Technology Inc All Rights Reserved
  4.  *
  5.  *
  6.  * 
  7.  * This module implements ZMODEM Run Length Encoding, an
  8.  * extension that was not funded by the original Telenet
  9.  * development contract.
  10.  * 
  11.  * This software may be freely used for non commercial and
  12.  * educational (didactic only) purposes.  This software may also
  13.  * be freely used to support file transfer operations to or from
  14.  * licensed Omen Technology products.  Any programs which use
  15.  * part or all of this software must be provided in source form
  16.  * with this notice intact except by written permission from Omen
  17.  * Technology Incorporated.
  18.  * 
  19.  * Use of this software for commercial or administrative purposes
  20.  * except when exclusively limited to interfacing Omen Technology
  21.  * products requires a per port license payment of $20.00 US per
  22.  * port (less in quantity).  Use of this code by inclusion,
  23.  * decompilation, reverse engineering or any other means
  24.  * constitutes agreement to these conditions and acceptance of
  25.  * liability to license the materials and payment of reasonable
  26.  * legal costs necessary to enforce this license agreement.
  27.  *
  28.  *
  29.  *        Omen Technology Inc        FAX: 503-621-3745
  30.  *        Post Office Box 4681
  31.  *        Portland OR 97208
  32.  *
  33.  *    This code is made available in the hope it will be useful,
  34.  *    BUT WITHOUT ANY WARRANTY OF ANY KIND OR LIABILITY FOR ANY
  35.  *    DAMAGES OF ANY KIND.
  36.  *
  37.  *    ZMODEM RLE compression and decompression functions
  38.  */
  39.  
  40. /* Send data subpacket RLE encoded with 32 bit FCS */
  41. zsdar32(buf, length, frameend)
  42. char *buf;
  43. {
  44.     register int c, l, n;
  45.     register UNSL long crc;
  46.  
  47.     crc = 0xFFFFFFFFL;  l = *buf++ & 0377;
  48.     if (length == 1) {
  49.         zsendline(l); crc = UPDC32(l, crc);
  50.         if (l == ZRESC) {
  51.             zsendline(1); crc = UPDC32(1, crc);
  52.         }
  53.     } else {
  54.         for (n = 0; --length >= 0; ++buf) {
  55.             if ((c = *buf & 0377) == l && n < 126 && length>0) {
  56.                 ++n;  continue;
  57.             }
  58.             switch (n) {
  59.             case 0:
  60.                 zsendline(l);
  61.                 crc = UPDC32(l, crc);
  62.                 if (l == ZRESC) {
  63.                     zsendline(0100); crc = UPDC32(0100, crc);
  64.                 }
  65.                 l = c; break;
  66.             case 1:
  67.                 if (l != ZRESC) {
  68.                     zsendline(l); zsendline(l);
  69.                     crc = UPDC32(l, crc);
  70.                     crc = UPDC32(l, crc);
  71.                     n = 0; l = c; break;
  72.                 }
  73.                 /* **** FALL THRU TO **** */
  74.             default:
  75.                 zsendline(ZRESC); crc = UPDC32(ZRESC, crc);
  76.                 if (l == 040 && n < 34) {
  77.                     n += 036;
  78.                     zsendline(n); crc = UPDC32(n, crc);
  79.                 }
  80.                 else {
  81.                     n += 0101;
  82.                     zsendline(n); crc = UPDC32(n, crc);
  83.                     zsendline(l); crc = UPDC32(l, crc);
  84.                 }
  85.                 n = 0; l = c; break;
  86.             }
  87.         }
  88.     }
  89.     xsendline(ZDLE); xsendline(frameend);
  90.     crc = UPDC32(frameend, crc);
  91.  
  92.     crc = ~crc;
  93.     for (length=4; --length >= 0;) {
  94.         zsendline((int)crc);  crc >>= 8;
  95.     }
  96. }
  97.  
  98.  
  99. /* Receive data subpacket RLE encoded with 32 bit FCS */
  100. zrdatr32(buf, length)
  101. register char *buf;
  102. {
  103.     register int c;
  104.     register UNSL long crc;
  105.     register char *end;
  106.     register int d;
  107.  
  108.     crc = 0xFFFFFFFFL;  Rxcount = 0;  end = buf + length;
  109.     d = 0;    /* Use for RLE decoder state */
  110.     while (buf <= end) {
  111.         if ((c = zdlread()) & ~0377) {
  112. crcfoo:
  113.             switch (c) {
  114.             case GOTCRCE:
  115.             case GOTCRCG:
  116.             case GOTCRCQ:
  117.             case GOTCRCW:
  118.                 d = c;  c &= 0377;
  119.                 crc = UPDC32(c, crc);
  120.                 if ((c = zdlread()) & ~0377)
  121.                     goto crcfoo;
  122.                 crc = UPDC32(c, crc);
  123.                 if ((c = zdlread()) & ~0377)
  124.                     goto crcfoo;
  125.                 crc = UPDC32(c, crc);
  126.                 if ((c = zdlread()) & ~0377)
  127.                     goto crcfoo;
  128.                 crc = UPDC32(c, crc);
  129.                 if ((c = zdlread()) & ~0377)
  130.                     goto crcfoo;
  131.                 crc = UPDC32(c, crc);
  132.                 if (crc != 0xDEBB20E3) {
  133.                     zperr(badcrc);
  134.                     return ERROR;
  135.                 }
  136.                 Rxcount = length - (end - buf);
  137. #ifndef DSZ
  138.                 vfile("zrdatr32: %d %s", Rxcount,
  139.                   Zendnames[d-GOTCRCE&3]);
  140. #endif
  141.                 return d;
  142.             case GOTCAN:
  143.                 zperr("Sender Canceled");
  144.                 return ZCAN;
  145.             case TIMEOUT:
  146.                 zperr("TIMEOUT");
  147.                 return c;
  148.             default:
  149.                 zperr("Bad data subpacket");
  150.                 return c;
  151.             }
  152.         }
  153.         crc = UPDC32(c, crc);
  154.         switch (d) {
  155.         case 0:
  156.             if (c == ZRESC) {
  157.                 d = -1;  continue;
  158.             }
  159.             *buf++ = c;  continue;
  160.         case -1:
  161.             if (c >= 040 && c < 0100) {
  162.                 d = c - 035; c = 040;  goto spaces;
  163.             }
  164.             if (c == 0100) {
  165.                 d = 0;
  166.                 *buf++ = ZRESC;  continue;
  167.             }
  168.             d = c;  continue;
  169.         default:
  170.             d -= 0100;
  171.             if (d < 1)
  172.                 goto badpkt;
  173. spaces:
  174.             if ((buf + d) > end)
  175.                 goto badpkt;
  176.             while ( --d >= 0)
  177.                 *buf++ = c;
  178.             d = 0;  continue;
  179.         }
  180.     }
  181. badpkt:
  182.     zperr("Data subpacket too long");
  183.     return ERROR;
  184. }
  185.  
  186.